﻿using System;
// 装箱时将数值类型实例转换成引用类型实例的行为。引用类型可以是object类或接口。
namespace _043_装箱和拆箱
{
    class Program
    {
        static void Main(string[] args)
        {
            // 本例中，我们将int类型装箱成一个object对象。
            int x = 9;
            object obj = x; // 把int类型装箱
            // 拆箱操作正好相反，它把object类型转换成原始的数值类型：
            int y = (int)obj; // 把int类型拆箱

            // 拆箱需要显式进行。
            // 运行时检查提供的值类型是否与真正的对象类型相匹配，并在检查出错误时，抛出InvalidCastException。
            // 例如，下面的例子抛出异常，因为long类型和int类型不匹配：
            object obj1 = 9; // 9被自动识别为int类型
            //long xl = (long)obj; // 抛出InvalidCastException
            long xl = (int)obj;// 正确写法

            object obj2 = 3.5; // 3.5被自动识别为double类型
            int xi2 = (int)(double)obj2; // xi2现在是3
            // (double)是拆箱操作，(int)是数值转换操作。

            // 装箱转换对系统提供一致的数据类型至关重要。但是这个体系并不是完美的：在“泛化”章节介绍，数组和泛型的变量只能支持引用转换，不能支持装箱转换：
            object[] a1 = new string[3]; // 合法
            //object[] a2 = new int[3]; // 出错

            // 装箱和拆箱的实质是复制
            int i = 3;
            object boxed = i;
            i = 5; 
            Console.WriteLine(boxed); // 3

            Console.ReadKey();
        }
    }
}
